<script setup lang="ts">
import {computed, onMounted, ref, h} from 'vue'
import {
  Button,
  Card,
  Form,
  Input,
  message,
  Modal,
  Space,
  Tree,
  Spin
} from 'ant-design-vue'
import { TreeSelect } from 'ant-design-vue'
import {
  BankOutlined,
  BookOutlined,
  TeamOutlined,
  DeleteOutlined,
  EditOutlined,
  PlusOutlined
} from '@ant-design/icons-vue'
import type {Organization} from '@/types/organization'
import {organizationApi} from '@/api/modules/organization'

// 组织类型定义
const organizationType = {
  COLLEGE: 1, // 学院
  MAJOR: 2,   // 专业
  CLASS: 3    // 班级
} as const

// 组织类型选项
const typeOptions = [
  { label: '学院', value: organizationType.COLLEGE },
  { label: '专业', value: organizationType.MAJOR },
  { label: '班级', value: organizationType.CLASS }
]

// 树形数据 - 初始化为空数组
const loading = ref(false)
const treeData = ref<Organization[]>([]) // 初始化为空数组而不是 undefined

// 选中的节点
const selectedKeys = ref<number[]>([])

// 表单数据
interface FormState {
  id?: number
  name: string
  parentId?: number | null
  type: number
  sort: number
  description: string
}

const formRef = ref()
const formState = ref<FormState>({
  name: '',
  parentId: null,
  type: organizationType.COLLEGE,
  sort: 0,
  description: ''
})

// 弹窗控制
const modalVisible = ref(false)
const modalTitle = ref('新增组织')
const modalLoading = ref(false)

// 转换树形数据为树节点数据
const treeNodes = computed(() => {
  const convert = (items: Organization[]): any[] => {
    if (!items?.length) return []
    return items.map(item => ({
      key: item.id,
      title: item.name,
      type: item.type,
      typeDesc: item.typeDesc,
      icon: () => {
        // 根据类型返回不同图标
        switch (item.type) {
          case organizationType.COLLEGE:
            return h(BankOutlined, { style: { color: '#1890ff' } })
          case organizationType.MAJOR:
            return h(BookOutlined, { style: { color: '#52c41a' } })
          case organizationType.CLASS:
            return h(TeamOutlined, { style: { color: '#faad14' } })
          default:
            return null
        }
      },
      children: item.children ? convert(item.children) : undefined,
      isLeaf: item.type === organizationType.CLASS
    }))
  }
  return convert(treeData.value)
})

// 处理选中节点
const handleSelect = (keys: number[], { node }: any) => {
  selectedKeys.value = keys
  rightClickNode.value = node
}

// 获取组织树形数据
const getOrganizationTree = async () => {
  loading.value = true
  try {
    const data  = await organizationApi.getTree()
    treeData.value = data || [] // 确保返回空数组
  } catch (error) {
    console.error('获取组织树形数据失败:', error)
    message.error('获取组织树形数据失败')
    treeData.value = [] // 错误时设置为空数组
  } finally {
    loading.value = false
  }
}

// 新增组织
const handleAdd = (node?: any) => {
  const type = node ? (node.type === organizationType.COLLEGE ? organizationType.MAJOR : organizationType.CLASS) : organizationType.COLLEGE
  formState.value = {
    name: '',
    parentId: node?.key || null,
    type: type,
    sort: 0,
    description: ''
  }
  modalTitle.value = '新增' + typeOptions.find(opt => opt.value === type)?.label
  modalVisible.value = true
}

// 编辑组织
const handleEdit = async (node: any) => {
  try {
    const data = await organizationApi.getById(node.key)
    formState.value = {
      id: data.id,
      name: data.name,
      parentId: data.parentId,
      type: data.type,
      sort: data.sort || 0,
      description: data.description || ''
    }
    modalTitle.value = '编辑' + typeOptions.find(opt => opt.value === data.type)?.label
    modalVisible.value = true
  } catch (error) {
    console.error('获取组织信息失败:', error)
    message.error('获取组织信息失败')
  }
}

// 删除组织
const handleDelete = (node: any) => {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除"${node.title}"吗？删除后将无法恢复！`,
    okText: '确认',
    okType: 'danger',
    cancelText: '取消',
    async onOk() {
      try {
        await organizationApi.delete(node.key)
        message.success('删除成功')
        getOrganizationTree()
      } catch (error) {
        console.error('删除失败:', error)
        message.error(error||'删除失败')
      }
    }
  })
}

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    modalLoading.value = true
    
    if (formState.value.id) {
      await organizationApi.update({
        ...formState.value,
        id: formState.value.id
      })
      message.success('更新成功')
    } else {
      await organizationApi.create(formState.value)
      message.success('创建成功')
    }
    
    modalVisible.value = false
    getOrganizationTree()
  } catch (error) {
    console.error('提交失败:', error)
    message.error(error||'提交失败')
  } finally {
    modalLoading.value = false
  }
}

// 右键菜单选项
const rightClickNode = ref<any>(null)
const menuVisible = ref(false)
const menuStyle = ref({ left: '0px', top: '0px' })

const handleRightClick = ({ event, node }: any) => {
  event.preventDefault()
  rightClickNode.value = node
  menuVisible.value = true
  menuStyle.value = {
    left: `${event.clientX}px`,
    top: `${event.clientY}px`
  }
}

// 修改树选择配置
const getTreeSelectProps = (formType: number, parentId?: number | null) => ({
  treeData: treeNodes.value,
  placeholder: '请选择上级组织',
  dropdownStyle: { maxHeight: '400px', overflow: 'auto' },
  allowClear: true,
  treeDefaultExpandAll: true,
  showSearch: true,
  fieldNames: {
    label: 'title',
    value: 'key',
    children: 'children'
  },
  filterTreeNode: (input: string, node: any) => {
    return node.title.toLowerCase().indexOf(input.toLowerCase()) >= 0
  },
  disabled: formType === organizationType.COLLEGE || parentId !== null
})

// 检查是否是子节点
const isChildNode = (node: Organization, targetId: number): boolean => {
  if (!node.children) return false
  return node.children.some(child => 
    child.id === targetId || isChildNode(child, targetId)
  )
}

// 添加表单规则
const formRules = {
  name: [{ required: true, message: '请输入组织名称' }],
  type: [{ required: true, message: '请选择组织类型' }]
}

// 添加类型变更处理
const handleTypeChange = (value: number) => {
  formState.value.type = value
  formState.value.parentId = null
}

// 计算是否显示上级组织选择
const showParentSelect = computed(() => formState.value.type !== organizationType.COLLEGE)

// 修改右键菜单图标
const getMenuIcon = (type: number) => {
  switch (type) {
    case organizationType.COLLEGE:
      return h(BookOutlined)
    case organizationType.MAJOR:
      return h(TeamOutlined)
    default:
      return h(PlusOutlined)
  }
}

// 初始化
onMounted(() => {
  getOrganizationTree()
})
</script>

<template>
  <div class="organization-page">
    <Card>
      <template #title>
        <BankOutlined style="margin-right: 8px" />
        组织架构管理
      </template>
      <template #extra>
        <Button type="primary" @click="handleAdd()">
          <template #icon><PlusOutlined /></template>
          新增学院
        </Button>
      </template>

      <div class="tree-container">
        <Tree
          v-if="!loading"
          :tree-data="treeNodes"
          :show-icon="true"
          :default-expand-all="true"
          :selected-keys="selectedKeys"
          @rightClick="handleRightClick"
          @select="handleSelect"
        />
        <div v-else class="loading-wrapper">
          <Spin />
        </div>
      </div>

      <!-- 右键菜单 -->
      <div
        v-if="menuVisible"
        class="context-menu"
        :style="menuStyle"
        @mouseleave="menuVisible = false"
      >
        <ul>
          <li v-if="rightClickNode?.type !== organizationType.CLASS" @click="handleAdd(rightClickNode)">
            <component :is="getMenuIcon(rightClickNode?.type)" />
            <span>新增{{ rightClickNode?.type === organizationType.COLLEGE ? '专业' : '班级' }}</span>
          </li>
          <li @click="handleEdit(rightClickNode)">
            <EditOutlined />
            <span>编辑</span>
          </li>
          <li @click="handleDelete(rightClickNode)">
            <DeleteOutlined />
            <span>删除</span>
          </li>
        </ul>
      </div>
    </Card>

    <!-- 新增/编辑弹窗 -->
    <Modal
      :title="modalTitle"
      :open="modalVisible"
      :maskClosable="false"
      :confirm-loading="modalLoading"
      @ok="handleSubmit"
      @cancel="modalVisible = false"
      ok-text="确定",
      cancel-text="取消"
    >
      <Form
        ref="formRef"
        :model="formState"
        :rules="formRules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <Form.Item
          label="组织类型"
          name="type"
          :rules="formRules.type"
        >
          <a-select
            v-model:value="formState.type"
            :options="typeOptions"
            placeholder="请选择组织类型"
            @change="handleTypeChange"
            :disabled="!!formState.id || formState.parentId !== null"
          />
        </Form.Item>

        <Form.Item
          v-if="showParentSelect"
          label="上级组织"
          name="parentId"
        >
          <TreeSelect
            v-model:value="formState.parentId"
            v-bind="getTreeSelectProps(formState.type, formState.parentId)"
            :tree-default-expand-all="true"
          />
        </Form.Item>

        <Form.Item
          label="组织名称"
          name="name"
          :rules="formRules.name"
        >
          <Input v-model:value="formState.name" placeholder="请输入组织名称" />
        </Form.Item>

        <Form.Item label="排序" name="sort">
          <Input
            v-model:value="formState.sort"
            type="number"
            placeholder="请输入排序号"
          />
        </Form.Item>

        <Form.Item label="描述" name="description">
          <Input.TextArea
            v-model:value="formState.description"
            placeholder="请输入描述信息"
          />
        </Form.Item>
      </Form>
    </Modal>
  </div>
</template>

<style lang="less" scoped>
.organization-page {
  :deep(.ant-card-body) {
    padding: 24px;
  }

  .tree-container {
    min-height: 400px;
    padding: 16px;
    background: #fafafa;
    border-radius: 4px;
  }

  .loading-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 400px;
  }

  .context-menu {
    position: fixed;
    z-index: 1000;
    background: white;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);

    ul {
      list-style: none;
      margin: 0;
      padding: 4px 0;

      li {
        padding: 8px 16px;
        cursor: pointer;
        transition: all 0.3s;
        display: flex;
        align-items: center;
        gap: 8px;

        &:hover {
          background: #f5f5f5;
        }

        .anticon {
          font-size: 14px;
          
          &.anticon-bank {
            color: #1890ff;
          }
          &.anticon-book {
            color: #52c41a;
          }
          &.anticon-team {
            color: #faad14;
          }
        }
      }
    }
  }

  :deep(.tree-node-icon) {
    display: none;
  }

  // 选中状态的样式
  :deep(.ant-tree-node-selected) {
    .tree-node-icon {
      box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    }
  }
}
</style> 